#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "thread.h"
#include "thread_list.h"
#include <assert.h>

//extern static int main_initialized;
extern thread_t* current_thread;
extern thread_t* maint;
extern thread_list* list_thread;
//extern int valgrind_stackid;
char test[8192];


int thread_create(thread_t *newthread, void *(*func)(void *), void *funcarg)
{
  static int max_thread_number=1;
  //static ucontext_t *last_used_uc;
  ucontext_t uc, uc1;
	//printf("on fait un thread create, le main_initialized vaut %d\n",main_initialized);

  if (main_initialized == 0)
    {
      thread_t *mainthread=malloc(sizeof(thread_t));
      mainthread->status=1;
      
      /*
		if (getcontext(&uc1) == -1)
		{
			printf(stderr, "erreur de getcontext");
			return -1;
		}
		uc1.uc_stack.ss_size = 64*1024;
		uc1.uc_stack.ss_sp = malloc(uc1.uc_stack.ss_size);*/
      
      //printf("le thread %d du main est créé\n",max_thread_number);
      mainthread->id=max_thread_number++;
      
      /*uc1.uc_stack.ss_size = 64*1024;
      uc1.uc_stack.ss_sp = malloc(uc1.uc_stack.ss_size);
      uc1.uc_link = NULL;
      */
      //mainthread->t=uc1;
      list_thread=init_thread_list();
      add_thread(list_thread, mainthread);
      current_thread=mainthread;
      //last_used_uc=uc1;
      main_initialized = 1;
      thread_remove=NULL;  
    }
    
    //printf("le thread %d est créé\n",max_thread_number);
    
  //uc = malloc(sizeof(ucontext_t));
  if (getcontext(&uc) == -1)
  {
    fprintf(stderr, "erreur de getcontext");
    return -1;
  }
  
  uc.uc_stack.ss_size = 64*1024;
  uc.uc_stack.ss_sp = malloc(uc.uc_stack.ss_size);
  /*
  uc->uc_link = NULL;
  last_used_uc=uc;
  makecontext(uc, (void(*)(void))func, 1, funcarg);
  valgrind_stackid = VALGRIND_STACK_REGISTER(uc->uc_stack.ss_sp, uc->uc_stack.ss_sp + uc->uc_stack.ss_size);
*/
  /*uc.uc_link = last_used_uc;
    last_used_uc= &uc;*/
  makecontext(&uc, (void(*)(void))func, 1, funcarg);
 
 //j'enleve car j'ai pas valgrind pour l'instant
  newthread->valgrind = VALGRIND_STACK_REGISTER(uc.uc_stack.ss_sp, uc.uc_stack.ss_sp + uc.uc_stack.ss_size);


  newthread->status=1;
  newthread->t = uc;
  /*  free(uc->uc_stack.ss_sp);
  free(uc);*/

  newthread->id=max_thread_number++;
  //fprintf(stderr,"nombre de thread :%d\n",max_thread_number);
  add_thread(list_thread, newthread);

	
  if (thread_yield()==-1)//swapcontext(previous, uc) == -1)
    return -1;
  
  
  return 0;
}
